package com.amigo.online.message.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.amigo.online.common.base.security.LocalUser;
import com.amigo.online.common.core.response.StatusCode;
import com.amigo.online.common.param.dto.group.NewGroupDto;
import com.amigo.online.common.param.result.GroupInfo;
import com.amigo.online.message.entity.MIMCJsonArrayResponse;
import com.amigo.online.message.entity.MIMCJsonResponse;
import com.amigo.online.message.entity.Topic;
import com.amigo.online.message.enums.MIMCUrlEnum;
import com.amigo.online.message.exception.GroupException;
import com.amigo.online.message.mapper.online.GroupMemberMapper;
import com.amigo.online.message.mapper.online.GroupMemberTblMapper;
import com.amigo.online.message.mapper.online.GroupTblMapper;
import com.amigo.online.message.mongo.dao.GroupDao;
import com.amigo.online.message.mybatisbean.GroupMemberTbl;
import com.amigo.online.message.mybatisbean.GroupTbl;
import com.amigo.online.message.mybatisbean.GroupTblExample;
import com.amigo.online.message.service.GroupService;
import com.amigo.online.message.util.BeanUtil;
import com.amigo.online.message.util.MIMCHttpUtil;
import com.amigo.online.common.core.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.guieffect.qual.UI;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Service
@Slf4j
public class GroupServiceImpl implements GroupService {

    @Autowired
    GroupTblMapper groupTblMapper;
    @Autowired
    GroupMemberTblMapper groupMemberTblMapper;
    @Autowired
    GroupMemberMapper groupMemberMapper;

    @Autowired
    private GroupDao groupDao;
    /**
     * 创建普通群聊
     * @param groupDto
     * @param uId
     * @return
     */
    @Override
    @Transactional(transactionManager = "onlineTransactionManager", rollbackFor = Exception.class)
    public GroupInfo foundTopic(NewGroupDto groupDto, Long uId) {

        ResponseEntity<MIMCJsonResponse> responseEntity = foundTopicMessage(groupDto.getName(), uId, groupDto.getMemberIds(), groupDto.getAvatar());
        GroupTbl groupTbl = new GroupTbl();
        if(responseEntity.getStatusCode().equals(HttpStatus.OK)){
            if(!responseEntity.getBody().getMessage().equals("success")){
                throw new GroupException(StatusCode.NEW_GROUP_FAILED);
            }else {
                groupTbl = BeanUtil.transformation(groupDto, groupTbl.getClass());
                groupTbl.setUserId(uId);
                groupTbl.setUpdatedTime(new Date().getTime()/1000);
                groupTbl.setCreatedUserId(uId);
                groupTbl.setCreatedTime(new Date().getTime()/1000);
                JSONObject responseJson = responseEntity.getBody().getData();
                groupTbl = foundTopic(responseJson, groupTbl);

                if(groupTbl==null){
                    throw new GroupException(StatusCode.NEW_GROUP_FAILED);
                }
                GroupInfo groupInfo = new GroupInfo();
                BeanUtils.copyProperties(groupDto, groupInfo);
                groupInfo.setGroupId(groupTbl.getId());
                groupInfo.setMemberNumber(groupDto.getMemberIds() == null ? 1 : groupDto.getMemberIds().size() + 1);
                groupInfo.setName(StringUtils.isBlank(groupDto.getName()) ? "" : groupDto.getName());
                groupInfo.setUserId(uId);

                groupDao.insertGroup(groupTbl);
                return groupInfo;
            }
        }else {
            throw new GroupException(StatusCode.NEW_GROUP_FAILED);
        }
    }

    /**
     * 邀请用户入群
     * @return
     */
    @Override
    @Transactional(transactionManager = "onlineTransactionManager", rollbackFor = Exception.class)
    public Result invitation(long groupId, List<Long> memberIds){
        String userId = LocalUser.getUser().getUser().getId().toString();
        ResponseEntity<MIMCJsonResponse> responseEntity = invitationMessage(userId,memberIds, groupId);
        if(responseEntity.getStatusCode().equals(HttpStatus.OK)){
            if(!responseEntity.getBody().getMessage().equals("success")){
                return Result.error("邀请失败");
            }else {
//                insertUser(memberIds, groupId);
                return Result.success("邀请成功");
            }
        }else {
            return Result.error("邀请失败");
        }
    }

    /**
     * 退群
     * @param groupId
     * @return
     */
    @Override
    @Transactional(transactionManager = "onlineTransactionManager", rollbackFor = Exception.class)
    public Result quitGroup(Long groupId){
        ResponseEntity<MIMCJsonResponse> responseEntity = quitGroupMessage(groupId);
        if(responseEntity.getStatusCode().equals(HttpStatus.OK)){
            if(responseEntity.getBody().getCode() != 200){
                return Result.error("退群失败");
            }else {
//                return quitGroup(userId, groupId);
                return Result.success();
            }

        }else {
            return Result.error("退群失败");
        }
    }

    /**
     * 解散群
     * @param userToken
     * @param topicId
     * @return
     */
    @Transactional(transactionManager = "onlineTransactionManager", rollbackFor = Exception.class)
    public Result dissolutionGroup(String userToken, Long topicId, long groupId){

        ResponseEntity<MIMCJsonResponse> responseEntity = dissolutionGroupMessage(userToken, topicId);
        if(responseEntity.getStatusCode().equals(HttpStatus.OK)){
            if(!responseEntity.getBody().getMessage().equals("成功！")){
                return Result.error("解散失败");
            }else {
                return dissolutionGroup(groupId);
            }
        }else {
            return Result.error("解散失败");
        }
    }

    /**
     * 查所属群信息
     * @param userId
     * @return
     */
    public Result selectOwnGroup(String userId){
        ResponseEntity<MIMCJsonArrayResponse> responseEntity = selectOwnGroupMessage(userId);
        if(responseEntity.getStatusCode().equals(HttpStatus.OK)){
            if(!responseEntity.getBody().getMessage().equals("success")){
                log.error(responseEntity.getBody().getMessage());
                return Result.error();
            }else {
                JSONArray jsonArray = responseEntity.getBody().getData();
                return selectOwnGroup(jsonArray);
            }
        }else {
            return Result.error();
        }
    }

    //    /**
//     * 查看指定群信息
//     * @param topicId
//     * @param token
//     * @return
//     */
//    @Override
//    public Result selectGroupByTopicId(String topicId){
//        ResponseEntity<MIMCJsonResponse> responseEntity = selectGroupByTopicIdMessage(topicId);
//        if(responseEntity.getStatusCode().equals(HttpStatus.OK)){
//            if(responseEntity.getBody().getCode()!=200){
//                return Result.error("查询失败");
//            }else {
//                JSONObject topicInfo = responseEntity.getBody().getData().getJSONObject("topicInfo");
//                Map<String, Object> map = new HashMap<>();
//                map.put("groupName" , topicInfo.getString("topicName"));
//                map.put("avatar", topicInfo.getString("extra"));
//                return Result.success(map);
//            }
//        }else {
//            return Result.error("查询失败");
//        }
//    }
    @Override
    public Result selectGroupByTopicId(Long topicId){
        GroupTbl groupTbl = groupTblMapper.selectByPrimaryKey(topicId);
        if (groupTbl == null){
            throw new GroupException(StatusCode.GROUP_NOT_FIND);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("groupName" , groupTbl.getName());
        map.put("avatar", groupTbl.getAvatar());
        return Result.success(map);
    }
    private Result selectOwnGroup(JSONArray miID){
        List<Long> list = new ArrayList<>();
        for (int i =0; i<miID.size();i++){
            list.add(miID.getJSONObject(i).getLong("topicId"));
        }
        GroupTblExample groupTblExample = new GroupTblExample();
        groupTblExample.createCriteria().andIdIn(list);
        List<GroupTbl> groupTbls = groupTblMapper.selectByExample(groupTblExample);
        return Result.success(groupTbls);
    }

    /**
     * 群主踢人退群
     * @param userToken
     * @param userId
     * @return
     */
    public Result kickQuitGroup(String userToken, String topicId, long userId, long groupId){
        ResponseEntity<MIMCJsonResponse> responseEntity = kickQuitGroupMessage(userToken,topicId, String.valueOf(userId));
        if(responseEntity.getStatusCode().equals(HttpStatus.OK)){
            if(!responseEntity.getBody().getMessage().equals("success")){
                return Result.error("踢人失败");
            }else {
                return quitGroup(userId ,groupId);
            }
        }else {
            return Result.error("踢人失败");
        }
    }

















    /**
     * 解散群--MIMC操作成功后修改数据库数据
     * @param groupId
     * @return
     */
    private Result dissolutionGroup(long groupId){
        GroupTbl groupTbl = new GroupTbl();
        groupTbl.setId(groupId);
        groupTbl.setDisbanded(true);
        groupTbl.setDisbandedTime(new Date().getTime()/1000);
        groupTblMapper.updateByPrimaryKeySelective(groupTbl);
        return Result.success("解散成功");
    }


    /**
     * 退群--MIMC操作成功后修改数据库数据
     * @param groupId
     * @return
     */
    private Result quitGroup(Long userId, Long groupId){
        GroupMemberTbl groupMemberTbl = new GroupMemberTbl();
        groupMemberTbl.setGroupId(groupId);
        groupMemberTbl.setUserId(userId);
        groupMemberTbl.setQuitTime(new Date().getTime()/1000);
        groupMemberMapper.quitGroup(groupMemberTbl);
        return Result.success("退群成功");
    }


    private GroupTbl foundTopic(JSONObject responseJson,  GroupTbl groupTbl){

        groupTbl.setId(responseJson.getJSONObject("topicInfo").getLong("topicId"));
        int ret = groupTblMapper.insertSelective(groupTbl);
        if(ret!=1){
            return null;
        }
        JSONArray jsonArray = responseJson.getJSONArray("members");
        insertUser(jsonArray, groupTbl.getId(),groupTbl.getUserId());
        return groupTbl;
    }
    /**
     * 插入用户
     * @param jsonArray JSON格式:
     *                  [
     *             {"uuid":$ownerUuid,"account":$ownerAccount},
     *             {"uuid":$userUuid1,"account":$userAccount1},
     *             {"uuid":$userUuid2,"account":$userAccount2},
     *             {"uuid":$userUuid3,"account":$userAccount3},
     *             {"uuid":$userUuid4,"account":$userAccount4},
     *             {"uuid":$userUuid5,"account":$userAccount5}
     *         ]
     * @param groupId
     * @return
     */
    private boolean insertUser(JSONArray jsonArray,  long groupId,long uId){

        for (int i=0;i<jsonArray.size();i++){
            GroupMemberTbl groupMemberTbl = new GroupMemberTbl();
            Long account = jsonArray.getJSONObject(i).getLong("account");
            if(uId== account){
                groupMemberTbl.setHost(true);
            }
            groupMemberTbl.setUserId(jsonArray.getJSONObject(i).getLong("account"));
            groupMemberTbl.setGroupId(groupId);
            groupMemberTbl.setCreatedTime(new Date().getTime()/1000);
            groupMemberTbl.setUpdatedTime(new Date().getTime()/1000);
            groupMemberTbl.setIsAllow(0);
            groupMemberTblMapper.insertSelective(groupMemberTbl);
        }
        return true;
    }

    /**
     * 将用户加入群成员表
     * @param idList
     * @param groupId
     * @return
     */
    private boolean insertUser(List<Long>  idList,  long groupId){

        groupMemberMapper.deleteEistingIds(groupId,idList);//先删除再添加
        for (int i=0;i<idList.size();i++){
            GroupMemberTbl groupMemberTbl = new GroupMemberTbl();
            groupMemberTbl.setUserId(idList.get(i));
            groupMemberTbl.setGroupId(groupId);
            groupMemberTbl.setCreatedTime(new Date().getTime()/1000);
            groupMemberTbl.setUpdatedTime(new Date().getTime()/1000);
            groupMemberTbl.setIsAllow(0);
            groupMemberTblMapper.insertSelective(groupMemberTbl);
        }
        return true;
    }

    /**
     * 发送建群消息
     * @param groupName
     * @param uId
     * @param extra
     * @return
     */
    private ResponseEntity<MIMCJsonResponse>  foundTopicMessage(String groupName, long uId, List<Long> memberIds, String extra){
        String accounts = splicingUserid(memberIds);
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(new Topic(groupName, accounts, extra)));
        RestTemplate restTemplate =new RestTemplate();
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(jsonObject, MIMCHttpUtil.getUserHttpHeaders(String.valueOf(uId)));
        ResponseEntity<MIMCJsonResponse> responseEntity =  restTemplate.exchange(MIMCUrlEnum.FOUND_GROUP.getValue(), HttpMethod.POST, requestEntity , MIMCJsonResponse.class);
        log.debug("发送建群消息返回值: " + responseEntity.getBody().getData());
        return responseEntity;
    }

    /**
     * 发送邀请用户进群消息
     * @param userToken
     * @param memberIds
     * @param topicId
     * @return
     */
    private ResponseEntity<MIMCJsonResponse>  invitationMessage(String userToken, List<Long> memberIds, Long topicId){
        //拼接用户ID字符串
        String accounts = splicingUserid(memberIds);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("accounts", accounts);
        RestTemplate restTemplate =new RestTemplate();
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(jsonObject, MIMCHttpUtil.getUserHttpHeaders(userToken));
        String INVITATION_GROUP = MIMCUrlEnum.INVITATION_GROUP.getValue();
        ResponseEntity<MIMCJsonResponse> responseEntity =  restTemplate.exchange(INVITATION_GROUP.replaceFirst("\\$topicId", topicId.toString()), HttpMethod.POST, requestEntity , MIMCJsonResponse.class);
        log.debug("发送建群消息返回值: " + responseEntity.getBody());
        return responseEntity;
    }

    /**
     * 发送退群消息
     * @param topicId
     * @return
     */
    private ResponseEntity<MIMCJsonResponse>  quitGroupMessage(Long groupId){
        Long uId = LocalUser.getUser().getUser().getId();
        RestTemplate restTemplate =new RestTemplate();
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(null, MIMCHttpUtil.getTokenHeaders(uId.toString()));
        String quitGroup = MIMCUrlEnum.QUIT_GROUP.getValue();
        ResponseEntity<MIMCJsonResponse> responseEntity =  restTemplate.exchange(quitGroup.replaceFirst("\\$topicId", groupId.toString()), HttpMethod.DELETE, requestEntity , MIMCJsonResponse.class);
        log.debug("发送退群消息返回值: " + responseEntity.getBody());
        return responseEntity;
    }
    /**
     * 发送解散群消息
     * @param userToken
     * @param topicId
     * @return
     */
    private ResponseEntity<MIMCJsonResponse>  dissolutionGroupMessage(String userToken, Long topicId){
        RestTemplate restTemplate =new RestTemplate();
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(null, MIMCHttpUtil.getTokenHeaders(userToken));
        String quitGroup = MIMCUrlEnum.DISSOLUTION_GROUP.getValue();
        ResponseEntity<MIMCJsonResponse> responseEntity =  restTemplate.exchange(MIMCUrlEnum.DISSOLUTION_GROUP.getValue()+ topicId.toString(), HttpMethod.DELETE, requestEntity , MIMCJsonResponse.class);
        log.debug("解散群消息返回值: " + responseEntity.getBody());
        return responseEntity;
    }
    /**
     * 查看指定群消息
     * @param topicId 群ID
     * @return
     */
    private ResponseEntity<MIMCJsonResponse> selectGroupByTopicIdMessage(String topicId){
        Long uId = LocalUser.getUser().getUser().getId();
        RestTemplate restTemplate =new RestTemplate();
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(null, MIMCHttpUtil.getUserHttpHeaders(uId.toString()));
        ResponseEntity<MIMCJsonResponse> responseEntity =  restTemplate.exchange(MIMCUrlEnum.SELECT_OWN_GROUP_BY_TOPICID.getValue() + topicId, HttpMethod.GET, requestEntity , MIMCJsonResponse.class);
        log.debug("查看指定群消息返回值: " + responseEntity.getBody());
        return responseEntity;
    }
    /**
     * 查看所属群消息
     * @param userId
     * @return
     */
    private ResponseEntity<MIMCJsonArrayResponse> selectOwnGroupMessage(String userId){
        RestTemplate restTemplate =new RestTemplate();
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(null, MIMCHttpUtil.getUserHttpHeaders(userId));
        ResponseEntity<MIMCJsonArrayResponse> responseEntity =  restTemplate.exchange(MIMCUrlEnum.SELECT_OWN_GROUP.getValue(), HttpMethod.GET, requestEntity , MIMCJsonArrayResponse.class);
        log.debug("解散群消息返回值: " + responseEntity.getBody());
        return responseEntity;
    }
    /**
     * 发送踢人退群消息
     * @param userToken
     * @return
     */
    private ResponseEntity<MIMCJsonResponse> kickQuitGroupMessage(String userToken, String topicId, String userId){
        RestTemplate restTemplate =new RestTemplate();
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(null, MIMCHttpUtil.getTokenHeaders(userToken));
        String kickQuitGroup = MIMCUrlEnum.KICK_QUIT_GROUP.getValue();
        ResponseEntity<MIMCJsonResponse> responseEntity =  restTemplate.exchange(kickQuitGroup.replace("topicId", topicId) + userId, HttpMethod.DELETE, requestEntity , MIMCJsonResponse.class);
        log.debug("解散群消息返回值: " + responseEntity.getBody());
        return responseEntity;
    }

    /**
     * 拼接用户ID
     * @param memberIds
     * @return
     */
    public static String splicingUserid(List<Long> memberIds ) {
        if(memberIds.size()==0){
            return null;
        }
        StringBuilder accounts = new StringBuilder();
        if(memberIds.size()<2){
            accounts.append(memberIds.get(0));
        }else {
            for(Long l: memberIds){
                accounts.append(l + ",");
            }
            accounts.deleteCharAt(accounts.length()-1);
        }
        return accounts.toString();
    }
}
